﻿using HCLSMod;
using LModBusRTU;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZLSerialPortBusLib.PLCManager;
using ZLSerialPortBusLib.SerialPortBus;
using ZLFMSTInputDialog;
using ZLSerialPortBusLib.LogView;

namespace ZLSerialPortBusLib
{
    public partial class FSerialPLCManager : Form, ZLFMFormModel
    {

        private ZLPLCBusOnSerialPort fSerialPortBus { get; set; }
        public ZLPLCBusOnSerialPort SerialPortBus { get { return fSerialPortBus; } }
        
        public int fBusIndex { get; set; }
        public bool ClearOnClose { get; set; }
                
        public bool BusReady { get; set; }
        #region 构建函数
        /// <summary>
        /// 直接使用默认Ini文件及0序号创建总线
        /// </summary>
        public FSerialPLCManager()
        {
            InitializeComponent();
            BusReady = false;
            ClearOnClose = true;
            fBusIndex = 0;
            ISerialPortBusCFG fSerialPortBusConfig = new SerialPortBusConfig(IniFile.NewIniFileName(), 0);
            fSerialPortBus = new ZLPLCBusOnSerialPort(fSerialPortBusConfig);
            numericUpDownSleepTick.Value = fSerialPortBus.SleepTick;
            numericUpDownTimeOut.Value = fSerialPortBus.ResponTimeOut;
            GetAllCFG();
            panelPLCInfo.Visible = false;
            groupBoxPLCInfo.Visible = false;
            BusReady = true;
        }

        /// <summary>
        /// 根据Ini文件名称及总线序号创建总线
        /// </summary>
        /// <param name="fIniFileName">Ini文件名称</param>
        /// <param name="fBusIdx">总线序号</param>
        public FSerialPLCManager(string fIniFileName,int fBusIdx)
        {
            InitializeComponent();
            BusReady = false;
            ClearOnClose = true;
            if (File.Exists(fIniFileName))
            {
                fBusIndex = fBusIdx;
                SerialPortBusConfig fSerialPortBusConfig = new SerialPortBusConfig(fIniFileName, fBusIdx);
                fSerialPortBus = new ZLPLCBusOnSerialPort(fSerialPortBusConfig);
                numericUpDownSleepTick.Value = fSerialPortBus.SleepTick;
                numericUpDownTimeOut.Value = fSerialPortBus.ResponTimeOut;
                GetAllCFG();
                panelPLCInfo.Visible = false;
                groupBoxPLCInfo.Visible = false;
                BusReady = true;
            }
        }
        /// <summary>
        /// 根据输入的配置对象创建总线
        /// </summary>
        /// <param name="fSerialPortBusCFG"></param>
        public FSerialPLCManager(ISerialPortBusCFG fSerialPortBusCFG)
        {
            InitializeComponent();
            BusReady = false;
            ClearOnClose = true;
            if (fSerialPortBusCFG != null)
            {
                fBusIndex = fSerialPortBusCFG.PortBusIdx;
                fSerialPortBus = new ZLPLCBusOnSerialPort(fSerialPortBusCFG);
                numericUpDownSleepTick.Value = fSerialPortBus.SleepTick;
                numericUpDownTimeOut.Value = fSerialPortBus.ResponTimeOut;
                GetAllCFG();
                panelPLCInfo.Visible = false;
                groupBoxPLCInfo.Visible = false;
                BusReady = true;
            }
        }
        /// <summary>
        /// 直接管理提供的总线
        /// </summary>
        /// <param name="fSerialPortBusX"></param>
        public FSerialPLCManager(ZLPLCBusOnSerialPort fSerialPortBusX)
        {
            InitializeComponent();
            BusReady = false;
            ClearOnClose = false;
            if ((fSerialPortBusX != null) && (fSerialPortBusX.PortBusCFG != null))
            {
                fSerialPortBus = fSerialPortBusX;
                numericUpDownSleepTick.Value = fSerialPortBus.SleepTick;
                numericUpDownTimeOut.Value = fSerialPortBus.ResponTimeOut;
                fSerialPortBus.StopBus();
                fBusIndex = fSerialPortBus.PortBusCFG.PortBusIdx;
                GetAllCFG();
                panelPLCInfo.Visible = false;
                groupBoxPLCInfo.Visible = false;
                BusReady = true;
            }
        }

        private void GetAllCFG()
        {
            listViewPLC.Items.Clear();
            comboBoxPortName.Items.Clear();
            comboBoxPortName.Items.AddRange(SerialPort.GetPortNames());
            if ((comboBoxPortName.Items.Count > 0)
                && (fSerialPortBus != null) && (fSerialPortBus.PortBusCFG != null))
            {
                checkBoxAutoStar.Checked = fSerialPortBus.PortBusCFG.AutoStar;
                comboBoxPortName.SelectedIndex = 0;
                for (int i = 0; i < comboBoxPortName.Items.Count; i++)
                    if (comboBoxPortName.Items[i].Equals(fSerialPortBus.PortBusCFG.PortName))
                    {
                        comboBoxPortName.SelectedIndex = i;
                        break;
                    }
                comboBoxBaudrate.SelectedIndex = 0;
                for (int i = 0; i < comboBoxBaudrate.Items.Count; i++)
                    if (int.Parse(comboBoxBaudrate.Items[i].ToString()) == fSerialPortBus.PortBusCFG.Baudrate)
                    {
                        comboBoxBaudrate.SelectedIndex = i;
                        break;
                    }
                int fIndex = (int)fSerialPortBus.PortBusCFG.CRCEndian - 1;
                comboBoxCRCEndian.SelectedIndex = (int)fSerialPortBus.PortBusCFG.CRCEndian - 1;
                comboBoxRSCON.SelectedIndex = (int)fSerialPortBus.PortBusCFG.RSConPORT;

                RebuildPLCList(fSerialPortBus.PortBusCFG.PLCInfoList);
            }
            toolStripStatusLabelIndex.Text = "Idx:" + fBusIndex.ToString();
            toolStripStatusLabelPipeName.Text = fSerialPortBus.PortBusCFG.PipeName;
        }

        private void RebuildPLCList(string[] fCFGList)
        {
            if (fCFGList != null)
            {
                fSerialPortBus.ReflashPLCRegList();
            }
            listViewPLC.Items.Clear();
            int[] fPLCAddressList = fSerialPortBus.PLCAddressList;
            if (fPLCAddressList.Length > 0)
                foreach (int fPLCAddr in fPLCAddressList)
                {
                    ZLPLCModbusNode fPLCNodeTemp = fSerialPortBus.GetPLCNode(fPLCAddr);
                    if (fPLCNodeTemp != null)
                    {
                        ListViewItem fLVItem = new ListViewItem(string.Format("0x{0:X2}({0})", fPLCAddr));
                        listViewPLC.Items.Add(fLVItem);
                        fLVItem.Tag = fPLCAddr;
                        // 寄存器起始地址
                        fLVItem.SubItems.Add(fPLCNodeTemp.RegStar.ToString());
                        // 寄存器数量
                        fLVItem.SubItems.Add(string.Format("0x{0:X2}({0})", 0));
                        // 刷新间隔
                        fLVItem.SubItems.Add("10");
                        // 错误累计
                        fLVItem.SubItems.Add("0");
                    }
                }
        }

        private void SaveAllCFG()
        {
            if (BusReady && (comboBoxPortName.Items.Count > 0)
                && (fSerialPortBus != null) && (fSerialPortBus.PortBusCFG != null))
            {
                fSerialPortBus.PortBusCFG.AutoStar=checkBoxAutoStar.Checked;
                fSerialPortBus.PortBusCFG.PortName = comboBoxPortName.Text;
                fSerialPortBus.PortBusCFG.Baudrate = string.IsNullOrEmpty(comboBoxBaudrate.Text) ? 9600 : int.Parse(comboBoxBaudrate.Text);
                int fIndex = comboBoxCRCEndian.SelectedIndex + 1;
                fSerialPortBus.PortBusCFG.CRCEndian = (TCRC16Endian)(comboBoxCRCEndian.SelectedIndex + 1);
                fSerialPortBus.PortBusCFG.RSConPORT = (SerialPortBus.TSerialRSCON)comboBoxRSCON.SelectedIndex;
                SerialPortBus.SaveAllPLCToCFG();
                toolStripStatusLabelPipeName.Text = fSerialPortBus.PortBusCFG.PipeName;
            }
        }

        #endregion

        #region 错误信息管理
        /// <summary>
        /// 错误信息列表
        /// </summary>
        protected List<string> fErrorInfo = new List<string>();
        /// <summary>
        /// 系统错误数量
        /// </summary>
        public int ErrorCount { get { return fErrorInfo.Count; } }
        /// <summary>
        /// 获得系统错误，将会清除错误
        /// </summary>
        /// <returns></returns>
        public string[] GetErrorInfo()
        {
            string[] fResult = fErrorInfo.ToArray();
            fErrorInfo.Clear();
            return fResult;
        }
        #endregion
        
        /// <summary>
        /// 获得串口总线描述信息
        /// 如果串口已经连接，则返回端口号、速度及RS控制端口，否则返回关闭
        /// </summary>
        /// <returns></returns>
        public string GetBusInfo()
        {
            string fResult = "Closed";

            if (fSerialPortBus.Active)
            {
                fResult = fSerialPortBus.SerialPortInfo;
            }
            return fResult;
        }

        #region 接口ZLFMFormModel功能函数
        public void SetParent(Control fParent)
        {
            this.FormBorderStyle = FormBorderStyle.None;
            this.Dock = DockStyle.Fill;
            this.TopLevel = false;
            this.Parent = fParent;
            this.Show();
        }

        public void CloseAll()
        {
            fSerialPortBus.CloseBus();
            Close();
        }
        #endregion

        #region PLC信息管理
        private void fDeamon_Tick(object sender, EventArgs e)
        {
            fDeamon.Enabled = false;
            try
            {
                if ((fSerialPortBus != null) && (fSerialPortBus.Active))
                {
                    buttonStarBus.Visible = false;
                    buttonStopBus.Visible = true;
                    panelCOMInfo.Enabled = false;
                    panelPLCInfo.Visible = true;

                    #region PLC信息列表维护
                    List<int> fPLCAddressList = new List<int>(fSerialPortBus.PLCAddressList);
                    if ((fPLCAddressList.Count > 0) && (this.Visible))
                    {
                        #region 确保显示的内容与列表一致，不一致则清除所有显示
                        if (listViewPLC.Items.Count != fPLCAddressList.Count)
                            listViewPLC.Items.Clear();
                        if (listViewPLC.Items.Count > 0)
                        {
                            // 清理列表中多出的记录！
                            if (listViewPLC.Items.Count > 0)
                                foreach (ListViewItem fLVNode in listViewPLC.Items)
                                {
                                    int fPLCAddr = 0;
                                    if ((fLVNode.Tag != null)
                                        && int.TryParse(fLVNode.Tag.ToString(), out fPLCAddr))
                                    {
                                        bool fHasFound = false;
                                        foreach (int fPLCAddrInList in fPLCAddressList)
                                            if (fPLCAddr == fPLCAddrInList)
                                            {
                                                fHasFound = true;
                                                break;
                                            }
                                        if (!fHasFound)
                                        {
                                            listViewPLC.Items.Clear();
                                            break;
                                        }
                                    }
                                }
                        }
                        
                        fPLCAddressList.Sort();
                        while (listViewPLC.Items.Count < fPLCAddressList.Count)
                        {
                            ListViewItem fItem = new ListViewItem();
                            listViewPLC.Items.Add(fItem);
                        }
                        #endregion

                        if (listViewPLC.Items.Count == fPLCAddressList.Count)
                            for (int i = 0; i < fPLCAddressList.Count; i++)
                            {
                                int fPLCAddress = 0;
                                if ((listViewPLC.Items[i].Tag != null) &&
                                    int.TryParse(listViewPLC.Items[i].Tag.ToString(), out fPLCAddress)
                                    && (fPLCAddress == fPLCAddressList[i]))
                                {
                                    ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fPLCAddressList[i]);
                                    if (fPLCNode != null)
                                    {
                                        listViewPLC.Items[i].SubItems[1].Text = fPLCNode.RegStar.ToString();
                                        listViewPLC.Items[i].SubItems[2].Text = string.Format("0x{0:X2}({0})", fPLCNode.RegCount);
                                        listViewPLC.Items[i].SubItems[3].Text = fPLCNode.IntervalOfFlash.ToString();
                                        listViewPLC.Items[i].SubItems[4].Text = fPLCNode.PLCDisconnectCount.ToString();
                                    }
                                }
                                else
                                {
                                    listViewPLC.Items[i].Tag = fPLCAddressList[i];
                                    listViewPLC.Items[i].SubItems.Clear();
                                    listViewPLC.Items[i].Text = string.Format("0x{0:X2}({0})", fPLCAddressList[i]);
                                    ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fPLCAddressList[i]);
                                    if (fPLCNode != null)
                                    {
                                        listViewPLC.Items[i].SubItems.Add(fPLCNode.RegStar.ToString());
                                        listViewPLC.Items[i].SubItems.Add(string.Format("0x{0:X2}({0})", fPLCNode.RegCount));
                                        listViewPLC.Items[i].SubItems.Add(fPLCNode.IntervalOfFlash.ToString());
                                        listViewPLC.Items[i].SubItems.Add(fPLCNode.PLCDisconnectCount.ToString());
                                    }
                                }
                            }
                    }
                    else
                    {
                        listViewPLC.Items.Clear();
                    }
                    #endregion

                    #region PLC寄存器值刷新
                    if (listViewPLC.SelectedItems.Count > 0)
                    {
                        int fPLCAddr = 0;
                        if (int.TryParse(listViewPLC.SelectedItems[0].Tag.ToString(), out fPLCAddr))
                        {
                            ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fPLCAddr);

                            if ((fPLCNode != null) && (!string.IsNullOrEmpty(fPLCNode.PLCSNStr)))
                            {
                                // 建立所有寄存器
                                if (listViewPLCRegValue.Items.Count != fPLCNode.RegCount)
                                {
                                    listViewPLCRegValue.Items.Clear();
                                    int fRegAddress = 0;
                                    while (listViewPLCRegValue.Items.Count < fPLCNode.RegCount)
                                    {
                                        ListViewItem fItem = new ListViewItem();
                                        fItem.SubItems.Add("");
                                        fItem.Tag = fRegAddress + fPLCNode.RegStar;
                                        fItem.Text = string.Format("0x{0:X4}({0})", fRegAddress + fPLCNode.RegStar);
                                        listViewPLCRegValue.Items.Add(fItem);
                                        fRegAddress++;
                                    }
                                }
                                if (fPLCNode.HasNewData)
                                    // 显示寄存器地址和值
                                    for (int i = 0; i < fPLCNode.RegCount; i++)
                                    {
                                        ushort fRegValue = 0;
                                        if (fPLCNode.ReadRegValue(i + fPLCNode.RegStar, out fRegValue))
                                            listViewPLCRegValue.Items[i].SubItems[1].Text = string.Format("0x{0:X4}", fRegValue);
                                        else
                                            listViewPLCRegValue.Items[i].SubItems[1].Text = "";

                                    }
                                if (fPLCNode.PLCDisconnectCount >= 5)
                                    for (int i = 0; i < fPLCNode.RegCount; i++)
                                        listViewPLCRegValue.Items[i].SubItems[1].Text = "0";
                            }
                        }
                    }
                    #endregion                    
                }
                else
                {
                    buttonStopBus.Visible = false;
                    buttonStarBus.Visible = true;
                    panelCOMInfo.Enabled = true;
                    panelPLCInfo.Visible = false;
                }
            }
            catch (Exception ex)
            {
                fErrorInfo.Add(string.Format("[{0}]:{1}",
                    DateTime.Now.ToString("HH:MM:SS fff"),
                    ex.Message));
            }
            finally
            {
                fDeamon.Enabled = true;
            }
        }

        #region PLC节点操作

        /// <summary>
        /// 将制定PLC的地址改为新的地址
        /// </summary>
        /// <param name="fOldPLCAddress">原PLC地址</param>
        /// <param name="fNewPLCAddress">新的PLC地址</param>
        public void SetPLCAddress(int fOldPLCAddress, int fNewPLCAddress)
        {
            if (fSerialPortBus.Active && (listViewPLC.SelectedItems.Count > 0))
            {
                ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fOldPLCAddress);
                if ((fPLCNode != null) && (!string.IsNullOrEmpty(fPLCNode.PLCSNStr)))
                {
                    int[] fDataBuf = new int[] { CRC16_GB19582.CRC16GB(fPLCNode.PLCSNByteLF, TCRC16Endian.Big),
                        fNewPLCAddress };   // 写入2个字节寄存器
                    TModbusRTUCommandV2 fCommand = new TModbusRTUCommandV2(ModbusCommand.WriteMemoryReg_0x10);
                    fCommand.PLCAddress = (byte)fOldPLCAddress;
                    fCommand.RegWriteAddress = 0;       // 写入本机地址
                    fCommand.RegWriteCount = (ushort)fDataBuf.Length;
                    for (int i = 0; i < fDataBuf.Length; i++)
                        fCommand.RegValue[i] = (ushort)fDataBuf[i];
                    int fTimeOut = 100;
                    fSerialPortBus.SendModbusCommand(fCommand, ref fTimeOut);
                }
            }
            else
                throw new Exception("目标PLC无法操作！");
        }

        /// <summary>
        /// 重启PLC
        /// </summary>
        /// <param name="fPLCAddress"></param>
        public void SetPLCReset(int fPLCAddress)
        {
            if (fSerialPortBus.Active && (listViewPLC.SelectedItems.Count > 0))
            {
                ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fPLCAddress);
                if ((fPLCNode != null) && (!string.IsNullOrEmpty(fPLCNode.PLCSNStr)))
                {
                    int[] fDataBuf = new int[] { CRC16_GB19582.CRC16GB(fPLCNode.PLCSNByteLF,TCRC16Endian.Big),
                        0 };        // 保证写入2个寄存器
                    TModbusRTUCommandV2 fCommand = new TModbusRTUCommandV2(ModbusCommand.WriteMemoryReg_0x10);
                    fCommand.PLCAddress = (byte)fPLCAddress;
                    fCommand.RegWriteAddress = 1;       // 写入重启PLC
                    fCommand.RegWriteCount = (ushort)fDataBuf.Length;
                    for (int i = 0; i < fDataBuf.Length; i++)
                        fCommand.RegValue[i] = (ushort)fDataBuf[i];
                    int fTimeOut = 100;
                    fSerialPortBus.SendModbusCommand(fCommand, ref fTimeOut);
                }
            }
            else
                throw new Exception("目标PLC无法操作！");
        }

        /// <summary>
        /// 写入PLC的序列号；需要在C8051F350模块上进行测试，确定序列号高低位对应
        /// </summary>
        /// <param name="fPLCSN"></param>
        /// <param name="fPLCAddress"></param>
        public void SetPLCSN(byte[] fPLCSN,int fPLCAddress)
        {
            if (fSerialPortBus.Active && (listViewPLC.SelectedItems.Count > 0))
            {
                ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fPLCAddress);
                if ((fPLCNode != null) && (!string.IsNullOrEmpty(fPLCNode.PLCSNStr)))
                {
                    List<ushort> fDataBuf = new List<ushort>();
                    fDataBuf.Add((ushort)CRC16_GB19582.CRC16GB(fPLCNode.PLCSNByteLF, TCRC16Endian.Big));
                    // 将要写入的PLCSN放入，转换为ushort，高位在前，写入缓冲区
                    for (int i=0;i<fPLCSN.Length;i++)
                    {
                        ushort fVTemp = 0;
                        if (i % 2 == 0)     //寄存器低位： 0,2,4,6,8,10,12,14,16,18,20,22
                            fVTemp = fPLCSN[i];
                        else
                        {       //寄存器高位： 1,3,5,7,9,11,13,15,17,19,21,23
                            ushort fVT1 = fPLCSN[i];
                            fVTemp |= (ushort)(fVT1 << 8);
                            fDataBuf.Add(fVTemp);
                        }
                    }
                    TModbusRTUCommandV2 fCommand = new TModbusRTUCommandV2(ModbusCommand.WriteMemoryReg_0x10);
                    fCommand.PLCAddress = (byte)fPLCAddress;
                    fCommand.RegWriteAddress = 2;       // 写入PLCSN，不是所有PLC都能够写入PLCSN
                    fCommand.RegWriteCount = (ushort)fDataBuf.Count;
                    for (int i = 0; i < fDataBuf.Count; i++)
                        fCommand.RegValue[i] = fDataBuf[i];
                    int fTimeOut = 100;
                    fSerialPortBus.SendModbusCommand(fCommand, ref fTimeOut);
                }
            }
            else
                throw new Exception("目标PLC无法操作！");
        }
        #endregion

        #region 界面按键
        private void buttonClear_Click(object sender, EventArgs e)
        {
            fSerialPortBus.ClearAllPLCNode();
            groupBoxPLCInfo.Visible = false;
        }

        private void buttonAddNewPLC_Click(object sender, EventArgs e)
        {
            int fPLCAddr = 0;
            int fPLCRegStar = 0;
            int fPLCRegCount = 0;
            if (InputBox_PLCInfo.InputPLCInfoBox(ref fPLCAddr, ref fPLCRegStar, ref fPLCRegCount)
                && (fPLCAddr > 0))
            {
                if (fSerialPortBus.GetPLCNode(fPLCAddr) == null)
                    fSerialPortBus.AddNewPLCNode(fPLCAddr, fPLCRegStar, fPLCRegCount);
                else
                    MessageBox.Show("已经存在相同地址的PLC！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonDeletePLC_Click(object sender, EventArgs e)
        {
            if (listViewPLC.SelectedItems.Count > 0)
            {
                byte fPLCAddr = 0;// Convert.ToInt32(listViewPLC.SelectedItems[0].Text.Substring(2), 16);
                if (byte.TryParse(listViewPLC.SelectedItems[0].Tag.ToString(), out fPLCAddr)
                    && (fPLCAddr > 0)&&
                    (MessageBox.Show("确认","确认删除？",MessageBoxButtons.YesNo,MessageBoxIcon.Warning)== DialogResult.Yes))
                {
                    fSerialPortBus.DelPLCNode(fPLCAddr);
                    groupBoxPLCInfo.Visible = false;
                }
            }
        }


        private void listViewPLC_SelectedIndexChanged(object sender, EventArgs e)
        {
            listViewPLCRegValue.Items.Clear();
            if (listViewPLC.SelectedItems.Count > 0)
            {
                groupBoxPLCInfo.Visible = true;
                int fPLCAddr = 0;// Convert.ToInt32(listViewPLC.SelectedItems[0].Text.Substring(2), 16);
                if ((listViewPLC.SelectedItems[0].Tag!=null)
                    &&(int.TryParse(listViewPLC.SelectedItems[0].Tag.ToString(), out fPLCAddr)))
                {
                    groupBoxPLCInfo.Text = string.Format("PLC:{0}", fPLCAddr);
                    ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fPLCAddr);
                    if (fPLCNode != null)
                    {
                        if (fPLCNode.PLCDisconnectCount>5)
                            buttonResetPLC.Enabled = true;
                        else
                            buttonResetPLC.Enabled = false;
                        if (fPLCNode.PLCDisconnectCount > 0)
                            buttonResetPLC.Enabled = true;
                        else
                            buttonResetPLC.Enabled = false; 
                        textBoxPLCSN.Text = fPLCNode.PLCSNStr;
                        numericUpDownFlash.Value = fPLCNode.IntervalOfFlash;
                    }
                }
            }
            else
            {
                groupBoxPLCInfo.Visible = false;
            }
        }

        #endregion

        #endregion

        private void buttonStarCOMPort_Click(object sender, EventArgs e)
        {
            if ((comboBoxPortName.SelectedIndex >= 0) && (comboBoxBaudrate.SelectedIndex >= 0)
                && (comboBoxCRCEndian.SelectedIndex >= 0) && (comboBoxRSCON.SelectedIndex >= 0))
            {
                fSerialPortBus.SleepTick = (int)numericUpDownSleepTick.Value;
                fSerialPortBus.ResponTimeOut = (int)numericUpDownTimeOut.Value;
                SaveAllCFG();
                fSerialPortBus.StarBus();
            }
            else
                throw new Exception("端口信息错误！");
        }        

        private void buttonResetPLC_Click(object sender, EventArgs e)
        {
            if (listViewPLC.SelectedItems.Count > 0)
            {
                int fOldPLCAddr = 0;
                if ((listViewPLC.SelectedItems[0].Tag != null)
                    && (int.TryParse(listViewPLC.SelectedItems[0].Tag.ToString(), out fOldPLCAddr)))
                {
                    ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fOldPLCAddr);
                    if (fPLCNode != null)
                    {
                        fPLCNode.ResetPLCConnect();
                    }
                }
            }
        }

        private void FSerialPLCManager_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (BusReady && ClearOnClose && (fSerialPortBus != null))
            {
                fSerialPortBus.CloseBus();
            }
            fSerialPortBus = null;
        }

        private void checkBoxAutoStar_CheckedChanged(object sender, EventArgs e)
        {
            SaveAllCFG();
        }

        private void buttonStopBus_Click(object sender, EventArgs e)
        {
            if ((fSerialPortBus != null) && (fSerialPortBus.Active))
            {
                fSerialPortBus.StopBus();
            }
        }

        private void numericUpDownFlash_ValueChanged(object sender, EventArgs e)
        {
            byte fPLCAddr = 0;// Convert.ToInt32(listViewPLC.SelectedItems[0].Text.Substring(2), 16);

            if ((listViewPLC.SelectedItems.Count > 0)
                &&(listViewPLC.SelectedItems[0].Tag!=null)
                && byte.TryParse(listViewPLC.SelectedItems[0].Tag.ToString(), out fPLCAddr)
                &&(fPLCAddr>0))
            {

                ZLPLCModbusNode fPLCNode = fSerialPortBus.GetPLCNode(fPLCAddr);
                if (fPLCNode != null)
                {
                    fPLCNode.IntervalOfFlash = (int)numericUpDownFlash.Value;
                    SaveAllCFG();
                }
            }
        }

        private void numericUpDownSleepTick_ValueChanged(object sender, EventArgs e)
        {
            fSerialPortBus.SleepTick= (int)numericUpDownSleepTick.Value;
            fSerialPortBus.ResponTimeOut = (int)numericUpDownTimeOut.Value;
        }

        #region 高级功能应用
        private void buttonSetSN_Click(object sender, EventArgs e)
        {
            // 内部测试使用
            if (listViewPLC.SelectedItems.Count > 0)
            {
                int fPLCAddr = 0;
                if (int.TryParse(listViewPLC.SelectedItems[0].Tag.ToString(), out fPLCAddr))
                {
                    string fSN = textBoxPLCSN.Text;
                    byte[] fPLCSNBytes = null;

                    if (InputBox_PLCSN.InputPLCSN(ref fSN,out fPLCSNBytes))
                    {
                        SetPLCSN(fPLCSNBytes, fPLCAddr);
                    }  
                }
            }
        }


        private void buttonSetPLCAddress_Click(object sender, EventArgs e)
        {
            if (listViewPLC.SelectedItems.Count > 0)
            {
                int fNewPLCAddr = 0;// Convert.ToInt32(listViewPLC.SelectedItems[0].Text.Substring(2), 16);
                int fOldPLCAddr = 0;
                if (int.TryParse(listViewPLC.SelectedItems[0].Tag.ToString(), out fOldPLCAddr))
                {
                    fNewPLCAddr = fOldPLCAddr;
                    if (InputBox_Int.InputIntBoxByte(ref fNewPLCAddr, "PLC地址:"))
                        // 功能需要等待测试
                        SetPLCAddress(fOldPLCAddr, fNewPLCAddr);
                }
            }
        }
        #endregion

        private void buttonShowLog_Click(object sender, EventArgs e)
        {
            if (!FLogView.LogViewRunning)
            {
                FLogView fLogView = new FLogView(fSerialPortBus);
                fLogView.Show();
            }
            else
                FLogView.LogViewFrom.Show();
        }
    }
}
